#!/usr/bin/python
# -*- coding: utf-8 -*-

# This file is part of Cockpit.
#
# Copyright (C) 2016 Red Hat, Inc.
#
# Cockpit is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Cockpit is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Cockpit; If not, see <http://www.gnu.org/licenses/>.

import parent
from testlib import *

import os

# The candlepin image has a lot of demo data preloaded
# useful info/commands:
#    Login: doc      password: password
#    org:   snowwhite
#
#    Login: admin    password: admin
#    org:   admin
#
# if you download product files onto the test machine, these will show up as installed products
# local directory: /etc/pki/product
# sample products used in the tests (different subscription results for doc and admin):
# /root/candlepin/generated_certs/6050.pem
# /root/candlepin/generated_certs/88888.pem
#
# to use the candlepin image on a test machine, either add the certificate or
# allow insecure connections (/etc/rhsm/rhsm.conf -> "insecure = 1")
#
# $IP is the ip of the candlepin machine
#
# add an activation key to a pool:
# curl --insecure --request POST --user admin:admin https://$IP:8443/candlepin/activation_keys/ff80808155ca50b10155ca50cd280010/pools/ff80808155ca50b10155ca51f04607e5
# register with: activation key "awesome_os_pool" and org "admin"
# or: subscription-manager register --activationkey awesome_os_pool --org admin --serverurl https://$IP:8443/candlepin

WAIT_SCRIPT = """
set -ex
for x in $(seq 1 200); do
    if curl --insecure -s https://%(addr)s:8443/candlepin; then
        break
    else
        sleep 1
    fi
done
"""

@skipImage("No subscriptions", "centos-7", "continuous-atomic", "debian-8", "debian-testing", "fedora-24", "fedora-25", "fedora-atomic", "fedora-testing", "ubuntu-1604")
class TestSubscriptions(MachineCase):
    additional_machines = {
        'candlepin': { 'machine': { 'image': 'candlepin' } }
    }

    def setUp(self):
        MachineCase.setUp(self)
        self.candlepin = self.machines['candlepin']

        # wait for candlepin to be active and verify
        self.candlepin.execute("systemctl start tomcat")

        # download product info from the candlepin machine
        product_file_one = os.path.join(self.tmpdir, "6050.pem")
        product_file_two = os.path.join(self.tmpdir, "88888.pem")
        self.candlepin.download("/root/candlepin/generated_certs/6050.pem", product_file_one)
        self.candlepin.download("/root/candlepin/generated_certs/88888.pem", product_file_two)

        # upload product info to the test machine
        m = self.machine
        m.upload([product_file_one, product_file_two], "/etc/pki/product")

        # make sure that rhsm skips certificate checks for the server
        m.execute("sed -i -e 's/insecure = 0/insecure = 1/g' /etc/rhsm/rhsm.conf")

        # Wait for the web service to be accessible
        args = { "addr": self.candlepin.address }
        m.execute(script=WAIT_SCRIPT % args)

    def testRegister(self):
        b = self.browser

        self.login_and_go("/subscriptions")

        # wait until we can open the registration dialog
        register_button_sel = "button.btn-primary:contains('Register')"
        b.wait_present(register_button_sel)
        b.wait_visible(register_button_sel)
        b.click(register_button_sel)

        b.wait_present("#subscription-register-url")
        b.wait_visible("#subscription-register-url")

        # optionally: check custom url
        b.click("#subscription-register-url button")
        b.wait_visible("#subscription-register-url .dropdown-menu")
        custom_url_selector = "#subscription-register-url a:contains('Custom')"
        b.wait_present(custom_url_selector)
        b.wait_visible(custom_url_selector)
        b.click(custom_url_selector)
        b.wait_not_present("#subscription-register-url.open")

        # enter server and incorrect login data
        b.wait_present("#subscription-register-url-custom")
        b.wait_visible("#subscription-register-url-custom")
        b.set_val("#subscription-register-url-custom", "{0}:8443/candlepin".format(self.candlepin.address))
        b.set_val("#subscription-register-username", "doc")
        b.set_val("#subscription-register-password", "wrongpass")

        # try to register
        dialog_register_button_sel = "div.modal-footer .btn-primary"
        b.click(dialog_register_button_sel)

        # wait for message that we used wrong credentials
        b.wait_in_text("body", "Invalid credentials")

        # enter correct login data and try again, old error should disappear
        b.set_val("#subscription-register-password", "password")
        b.click(dialog_register_button_sel)

        b.wait_not_in_text("body", "Invalid credentials")

        # wait for message that we need to specify our org
        b.wait_in_text("body", "'Organization' required to register.")

        # now specify the org
        b.set_val("#subscription-register-org", "admin")

        # use an activation key
        self.candlepin.execute("curl --insecure --request POST --user admin:admin https://localhost:8443/candlepin/activation_keys/ff80808155ca50b10155ca50cd280010/pools/ff80808155ca50b10155ca51f04607e5")
        b.set_val("#subscription-register-username", "")
        b.set_val("#subscription-register-password", "")
        b.set_val("#subscription-register-password", "")
        b.set_val("#subscription-register-key", "awesome_os_pool")

        # try to register again
        b.click(dialog_register_button_sel)

        # old error should disappear
        b.wait_not_in_text("body", "'Organization' required to register.")

        # dialog should disappear
        b.wait_not_present(dialog_register_button_sel)

        # make sure this product isn't subscribed
        product_selector = "tr.listing-ct-item:contains('Snowy OS Premium Architecture Bits')"
        b.wait_present(product_selector)
        # expand
        b.click(product_selector)
        details_selector = "tr.listing-ct-panel:contains('Snowy OS Premium Architecture Bits')"
        b.wait_in_text(details_selector, "6050")
        b.wait_in_text(details_selector, "Not Subscribed")
        # collapse again
        b.click(product_selector)

        # find another one that is subscribed
        product_selector = "tr.listing-ct-item:contains('Shared File System Bits')"
        b.wait_present(product_selector)
        # expand
        b.click(product_selector)
        details_selector = "tr.listing-ct-panel:contains('Shared File System Bits')"
        b.wait_in_text(details_selector, "88888")
        b.wait_not_in_text(details_selector, "Not Subscribed")
        # collapse again
        b.click(product_selector)

        # unregister
        unregister_button_sel = "button.btn-primary:contains('Unregister')"
        b.wait_present(unregister_button_sel)
        b.wait_visible(unregister_button_sel)
        b.click(unregister_button_sel)

        # wait until we can register again and open the dialog
        # wait until we can open the registration dialog
        b.wait_present(register_button_sel)
        b.wait_visible(register_button_sel)
        b.click(register_button_sel)

        b.wait_present("#subscription-register-url")
        b.wait_visible("#subscription-register-url")

        # check custom url
        b.click("#subscription-register-url button")
        b.wait_visible("#subscription-register-url .dropdown-menu")
        custom_url_selector = "#subscription-register-url a:contains('Custom')"
        b.wait_present(custom_url_selector)
        b.wait_visible(custom_url_selector)
        b.click(custom_url_selector)
        b.wait_not_present("#subscription-register-url.open")

        # enter server data
        b.wait_present("#subscription-register-url-custom")
        b.wait_visible("#subscription-register-url-custom")
        b.set_val("#subscription-register-url-custom", "{0}:8443/candlepin".format(self.candlepin.address))

        # make sure we have an activation key on the target machine
        self.candlepin.execute("curl --insecure --request POST --user admin:admin https://localhost:8443/candlepin/activation_keys/ff80808155ca50b10155ca50cd280010/pools/ff80808155ca50b10155ca51f04607e5")

        # enter key and org
        b.set_val("#subscription-register-key", "awesome_os_pool")
        b.set_val("#subscription-register-org", "admin")
        b.click(dialog_register_button_sel)

        # dialog should disappear
        b.wait_not_present(dialog_register_button_sel)

        # make sure this product isn't subscribed
        product_selector = "tr.listing-ct-item:contains('Snowy OS Premium Architecture Bits')"
        b.wait_present(product_selector)
        # expand
        b.click(product_selector)
        details_selector = "tr.listing-ct-panel:contains('Snowy OS Premium Architecture Bits')"
        b.wait_in_text(details_selector, "6050")
        b.wait_not_in_text(details_selector, "Not Subscribed")
        # collapse again
        b.click(product_selector)

if __name__ == '__main__':
    test_main()
